#include "../source/server.hpp"
#include <iostream>

using namespace std;

// #define MIN(type) \
// type type##_min(type x, type y)\
// {\
//     return x < y ? x : y;\
// }
void TestBuffer()
{
    // Buffer buffer(10);
    // cout << "Initial buffer size: " << buffer.IdleSize() << endl;

    // string data = "Hello";
    // buffer.WriteStringAndPush(data);
    // cout << "After writing string, Idle size: " << buffer.IdleSize() << endl;

    // string read_data = buffer.ReadString(data.size());
    // cout << "Read data: " << read_data << ", Idle size: " << buffer.IdleSize() << endl;

    // buffer.WriteStringAndPush("World!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    // cout << "After writing another string, Idle size: " << buffer.IdleSize() << endl;

    // read_data = buffer.ReadString(63);
    // cout << "Read data: " << read_data << ", Idle size: " << buffer.IdleSize() << endl;

    // Buffer buffer2(10);
    // buffer2.WriteStringAndPush("12");
    // buffer2.WriteBufferAndPush(buffer);

    // cout << buffer2.ReadString(65) << endl;

    // Buffer b;
    // for(int i = 0; i < 1000; ++i)
    // {
    //     string s = to_string(i) + "\r\n";
    //     b.WriteStringAndPush(s);
    // }

    // cout << b.ReadStringAndPop(b.EffectiveDataSize());
    // for(int i=0;i<1000;++i)
    // {
    //     string s;
    //     cout << (s = b.GetLineAndPop());
    //     if(i != stoi(s))
    //     {
    //         cout << "false\n";
    //         exit(1);
    //     }
    // }
}

void TestLOG()
{
    // #define LOG(format, ...) printf("[%s, %d]" format, __FILE__, __LINE__,##__VA_ARGS__)
    // const char* a = "ab";
    // LOG("%s", a);

    // auto t = time(nullptr);
    // tm* now = localtime(&t);
    // char p[64];
    // strftime(p, 30, "%Y-%m-%d %H:%M:%S", now);
    DEBUG_LOG("%s", "a");
}

void TestSocketServer()
{
    Socket server;
    server.CreateServer(8080, true);
    while (true)
    {
        // int client_sockfd = server.Accept();

        // Socket client(client_sockfd);

        // client.Send("Hello, client!", 15);

        // char buffer[1024] = {0};
        // ssize_t ret = client.Recv(buffer, sizeof(buffer) - 1);
        // DEBUG_LOG("Received from client: %s", buffer);
    }
}

// class MyClass {
// public:
//     MyClass(const std::string& data) : _data(data) {
//         std::cout << "Copy constructor called\n";
//     }

//     MyClass(std::string&& data) : _data(std::move(data)) {
//         std::cout << "Move constructor called\n";
//     }

// private:
//     std::string _data;
// };

// void Process(MyClass obj) {
//     // 按值传递，可能触发拷贝或移动构造
// }

void test()
{
    // std::string temp = "Hello";

    // // 非临时对象，触发拷贝构造
    // Process(MyClass(temp));

    // // 临时对象，触发移动构造
    // Process(MyClass("Temporary Object"));

    const int *p = nullptr;
    int a = 1;
    p = &a;
}

namespace TestChannelEventLoop
{
    // void CloseCallback(EventLoop* loop, Channel* channel, uint64_t task_id)
    // {
    //     loop->TimerCancel(task_id); // 取消定时任务
    //     // 处理连接关闭
    //     DEBUG_LOG("Connection closed, fd: %d", channel->Fd());
    //     delete channel; // 删除Channel对象
    // }
    // void ReadCallback(EventLoop* loop, Channel* channel, uint64_t task_id)
    // {
    //     char buffer[1024] = {0};
    //     ssize_t n = recv(channel->Fd(), buffer, sizeof(buffer) - 1, 0);
    //     if(n <= 0)
    //     {
    //         if(errno == EINTR || errno == EAGAIN)
    //         {
    //             DEBUG_LOG("Read interrupted or no data, fd: %d", channel->Fd());
    //             return; // 中断或无数据
    //         }
    //         ERROR_LOG("Read from socket failed, fd: %d, error: %s", channel->Fd(), strerror(errno));
    //         // ERROR_LOG("%d", n);
    //         CloseCallback(loop, channel, task_id); // 关闭连接
    //         return;
    //     }
    //     DEBUG_LOG("Read %ld bytes from fd: %d, %s", n, channel->Fd(), buffer);
    //     channel->EnableWrite();
    // }
    // void WriteCallback(EventLoop* loop, Channel* channel, uint64_t task_id)
    // {
    //     const char* message = "Hello, client!";
    //     ssize_t n = send(channel->Fd(), message, strlen(message), 0);
    //     if(n < 0)
    //     {
    //         if(errno == EINTR || errno == EAGAIN)
    //         {
    //             DEBUG_LOG("Write interrupted or no data, fd: %d", channel->Fd());
    //             return; // 中断或无数据
    //         }
    //         ERROR_LOG("Write to socket failed, fd: %d, error: %s", channel->Fd(), strerror(errno));
    //         CloseCallback(loop, channel, task_id); // 关闭连接
    //         return;
    //     }
    //     DEBUG_LOG("Wrote %zd bytes to fd: %d", n, channel->Fd());
    //     channel->DisableWrite();
    // }

    // void AnyCallback(EventLoop* event_loop, Channel* channel, uint64_t task_id)
    // {
    //     //刷新定时任务
    //     event_loop->TimerRefresh(task_id);
    // }
    // void ErrorCallback(Channel* channel)
    // {
    //     // 处理错误事件
    //     ERROR_LOG("Error occurred on fd: %d", channel->Fd());
    //     CloseCallback(channel);
    // }

    std::vector<LoopThread> threads(2); // 全局事件循环线程池

    int next_loop = 0;
    std::unordered_map<uint64_t, PtrConnection> g_connections; // 全局连接映射表
    uint64_t conn_id = 0;     // 全局连接ID
    void OnMessage(const PtrConnection &conn, Buffer &buf)
    {
        DEBUG_LOG("Received message from connection %p, data size: %zu", conn.get(), buf.EffectiveDataSize());
        buf.MoveReadOffset(buf.EffectiveDataSize());
        conn->Send("hello, world\n", 16);
    }

    void OnConnected(const PtrConnection &conn)
    {
        DEBUG_LOG("NEW CONNECTION: %p", conn.get());
    }

    void OnClosed(const PtrConnection &conn)
    {
        DEBUG_LOG("CLOSED CONNECTION: %p", conn.get());
        g_connections.erase(conn->Id()); // 从全局连接映射表中删除连接
    }


    void ListenerCallback(int conn_fd)
    {
        EventLoop *loop = threads[(next_loop + 1) % threads.size()].GetLoop(); // 获取下一个事件循环
        PtrConnection conn = std::make_shared<Connection>(loop, conn_id, conn_fd);
        g_connections[conn_id] = conn; // 存储连接
        ++conn_id; // 增加连接ID
        // conn->SetMessageCallback(std::bind(OnMessage, std::placeholders::_1));
        conn->SetMessageCallback([&](const PtrConnection &p, Buffer &b)
                                 { OnMessage(p, b); });
        conn->SetClosedCallback(std::bind(OnClosed, std::placeholders::_1));
        conn->SetConnectedCallback(std::bind(OnConnected, std::placeholders::_1));
        conn->EnableInactiveRelease(5); // 启用非活动释放
        conn->Establish();
    }
    void TestChennelAndEventLoop()
    {
        // 以epoll为中心，服务器只关心封装fd的channel，只需要把channel注册到epoll上即可
        // epoll会负责监听channel的事件
        // epoll遍历所有注册进去的fd和事件后，返回活跃的channel
        // 服务器不关心活跃的channel具体要做什么
        // 只需要调用活跃channel的HandleEvent函数即可

        // 服务器只需要
        // 往epoll里填fd和事件
        // 遍历epoll_wait的返回channels
        // 调用channel::HandleEvent
        // int pos = (next_loop + 1) % threads.size();
        // EventLoop *loop = threads[pos].GetLoop(); // 获取下一个事件循环
        EventLoop loop;
        Accepter listener(&loop, 8000);
        listener.SetAcceptCallback(std::bind(ListenerCallback, std::placeholders::_1));
        listener.Listen();
        loop.Start(); // 启动事件循环
    }
}

int main()
{
    // test();
    // TestSocketServer();
    TestChannelEventLoop::TestChennelAndEventLoop();
    return 0;
}